package de.teamgamma.cansat.groundstation.livestream;

import info.monitorenter.gui.chart.Chart2D;
import info.monitorenter.gui.chart.ITrace2D;
import info.monitorenter.gui.chart.traces.Trace2DLtd;

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.text.DefaultCaret;

import de.szut.gui.language.Languages;
import de.szut.gui.language.TranslatableComponent;
import de.szut.gui.language.TranslatableLabel;
import de.szut.gui.language.TranslatableStyledButton;
import de.teamgamma.cansat.groundstation.control.Controller;
import de.teamgamma.cansat.groundstation.control.GUIController;
import de.teamgamma.cansat.groundstation.main.DefaultPanel;
import de.teamgamma.cansat.groundstation.main.MainMenuPanel;
import de.teamgamma.cansat.groundstation.options.OptionKeys;

/**
 * Panel of the livestream
 * @author Marc Huisinga
 *
 */

public class LivestreamPanel extends DefaultPanel {
	
	/**
	 * Max. amount of points on the graph
	 */
	public static final int TRACERMAXVALUES = 40;
	/**
	 * Default-Width of the graph
	 */
	public static final int GRAPHWIDTH = 380;
	/**
	 * Default-Height of the graph
	 */
	public static final int GRAPHHEIGHT = 280;
	/**
	 * Default X-Position of the graph
	 */
	public static final int GRAPHX = Controller.getInstance().getGuiController().getMainFrame().getWidth()-GRAPHWIDTH-20;
	/**
	 * Default Y-Position of the graph
	 */
	public static final int GRAPHY = Controller.getInstance().getGuiController().getMainFrame().getHeight()-GRAPHHEIGHT-70;
	/**
	 * Default boolean if the graph is supposed to use antialising
	 */
	public static final boolean USEANTIALISING = true;
	
	private static final long serialVersionUID = 4110714490495665615L;

	private ArrayList<TranslatableComponent> translatableComponents;
	
	private Chart2D chart;
	private ITrace2D trace;
	private Livestream stream;
	private boolean debug;
	private JTextArea displayArea;
	private TranslatableStyledButton pause;
	private TranslatableStyledButton stop;
	private LivestreamMenuBar menuBar;

	public LivestreamPanel() {
		if (Controller.getInstance().getOptions().getOptionValue(OptionKeys.DEBUGMODE).equals("1")) {
			debug = true;
		} else {
			debug = false;
		}
		
		translatableComponents = new ArrayList<TranslatableComponent>();
		
		Languages.prepareComponent("livestream.LivestreamPanel.header", getHeader(), translatableComponents);
		Languages.prepareComponent("livestream.LivestreamPanel.return", getReturnButton(), translatableComponents);
		getReturnButton().addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				Controller.getInstance().getGuiController().toggleCurrentPanel(new MainMenuPanel());
				if (debug) {
					stream.stopDebugStream();
				} else {
					stream.stopStream();
				}
				menuBar.saveStates();
			}
		});
		
		chart = new Chart2D();
		chart.setUseAntialiasing(USEANTIALISING);
		chart.getAxisX().setPaintScale(true);
		chart.getAxisX().setPaintGrid(true);
		chart.getAxisY().setPaintGrid(true);
		chart.setPaintLabels(false);
		chart.setBorder(GUIController.COMPONENTBORDER);
		trace = new Trace2DLtd(TRACERMAXVALUES);
		chart.addTrace(trace);
		chart.setBounds(GRAPHX, GRAPHY, GRAPHWIDTH, GRAPHHEIGHT);
		add(chart);
		
		menuBar = new LivestreamMenuBar(this);
		add(menuBar);
		
		stream = new Livestream(this);
		if (debug) {
			stream.startDebugStream();
		} else {
			stream.startStream();
		}
		
		
		TranslatableLabel dataStream = new TranslatableLabel();
		Languages.prepareComponent("livestream.LivestreamPanel.datastreaminfo", dataStream, translatableComponents);
		dataStream.setBounds(0, menuBar.getY()+menuBar.getHeight()+2, menuBar.getWidth(), menuBar.getHeight());
		add(dataStream);
		
		displayArea = new JTextArea();
		displayArea.setEditable(false);
		((DefaultCaret)displayArea.getCaret()).setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
		JScrollPane scroll = new JScrollPane(displayArea);
		scroll.setAutoscrolls(true);
		scroll.setBounds(0, dataStream.getY()+dataStream.getHeight()+2, 202, GRAPHHEIGHT-10);
		add(scroll);
		
		pause = new TranslatableStyledButton();
		pause.setFont(new Font("Tahoma", Font.PLAIN, 14));
		Languages.prepareComponent("livestream.LivestreamPanel.pause", pause, translatableComponents);
		pause.setBounds(getReturnButton().getX()-getReturnButton().getWidth()-10, getReturnButton().getY(), getReturnButton().getWidth(), getReturnButton().getHeight());
		pause.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent event) {
				stream.toggleStreamPaused();
			}
		});
		add(pause);
		
		stop = new TranslatableStyledButton();
		stop.setFont(new Font("Tahoma", Font.PLAIN, 14));
		Languages.prepareComponent("livestream.LivestreamPanel.stop", stop, translatableComponents);
		stop.setBounds(pause.getX()-pause.getWidth()-10, getReturnButton().getY(), getReturnButton().getWidth(), getReturnButton().getHeight());
		stop.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent event) {
				stream.toggleStreamStopped();
			}
		});
		add(stop);
		
		Controller.getInstance().getGuiController().getLanguages().translateListOfComponents(translatableComponents);
		
		for (AxisMenuRadioButton currentButton : menuBar.getxAxis().getAxisButtons()) {
			if (currentButton.isSelected()) {
				stream.setCurrentXAxisValue(currentButton.getTransmissionKey());
			}
		}
		
		for (AxisMenuRadioButton currentButton : menuBar.getyAxis().getAxisButtons()) {
			if (currentButton.isSelected()) {
				stream.setCurrentYAxisValue(currentButton.getTransmissionKey());
			}
		}
	}
	
	/**
	 * Gets the translatable components of the LivestreamPanel
	 * @return translatable components
	 */
	public ArrayList<TranslatableComponent> getTranslatableComponents() {
		return translatableComponents;
	}

	/**
	 * Sets the translatable components of the LivestreamPanel
	 * @param translatableComponents
	 */
	public void setTranslatableComponents(
			ArrayList<TranslatableComponent> translatableComponents) {
		this.translatableComponents = translatableComponents;
	}

	/**
	 * Gets the chart on this panel
	 * @return chart
	 */
	public Chart2D getChart() {
		return chart;
	}

	/**
	 * Sets the chart on this panel
	 * @param chart
	 */
	public void setChart(Chart2D chart) {
		this.chart = chart;
	}

	/**
	 * Gets the trace of the chart on this panel
	 * @return trace of the chart on this panel
	 */
	public ITrace2D getTrace() {
		return trace;
	}

	/**
	 * Sets the trace of the chart on this panel
	 * @param trace
	 */
	public void setTrace(ITrace2D trace) {
		this.trace = trace;
	}

	/**
	 * Returns if the stream is in debug mode
	 * @return debug
	 */
	public boolean isDebug() {
		return debug;
	}

	/**
	 * Sets the debug-state of the stream
	 * @param debug - debug state of the stream
	 */
	public void setDebug(boolean debug) {
		this.debug = debug;
	}

	/**
	 * Gets the livestream of this panel
	 * @return livestream
	 */
	public Livestream getStream() {
		return stream;
	}

	/**
	 * Sets the livestream of this panel
	 * @param stream
	 */
	public void setStream(Livestream stream) {
		this.stream = stream;
	}
	
	/**
	 * Gets the name of the x axis from the respective key
	 * @param key
	 * @return name
	 */
	public String getXAxisNameFromKey(String key) {
		return menuBar.getxAxis().getAxisNameFromKey(key);
	}
	
	/**
	 * Gets the name of the y axis from the respective key
	 * @param key
	 * @return name
	 */
	public String getYAxisNameFromKey(String key) {
		return menuBar.getyAxis().getAxisNameFromKey(key);
	}

	/**
	 * Gets the display area where data is displayed
	 * @return display area
	 */
	public JTextArea getDisplayArea() {
		return displayArea;
	}

	/**
	 * Sets the display area where data is displayed
	 * @param displayArea
	 */
	public void setDisplayArea(JTextArea displayArea) {
		this.displayArea = displayArea;
	}

	/**
	 * Gets the pause button
	 * @return pause button
	 */
	public TranslatableStyledButton getPause() {
		return pause;
	}

	/**
	 * Sets the pause button
	 * @param pause - pause button
	 */
	public void setPause(TranslatableStyledButton pause) {
		this.pause = pause;
	}

	/**
	 * Gets the stop button
	 * @return stop button
	 */
	public TranslatableStyledButton getStop() {
		return stop;
	}

	/**
	 * Sets the stop button
	 * @param stop - stop button
	 */
	public void setStop(TranslatableStyledButton stop) {
		this.stop = stop;
	}

	/**
	 * Gets the menu bar on the panel
	 * @return menu bar
	 */
	public LivestreamMenuBar getMenuBar() {
		return menuBar;
	}

	/**
	 * Sets the menu bar on the panel
	 * @param menuBar
	 */
	public void setMenuBar(LivestreamMenuBar menuBar) {
		this.menuBar = menuBar;
	}

}
